package com.xyxeshang.es.music.backend.aop;



import com.xyxeshang.es.music.backend.annotation.JwtCheck;
import com.xyxeshang.es.music.backend.constant.ResultConstant;
import com.xyxeshang.es.music.backend.exception.CustomException;
import com.xyxeshang.es.music.backend.util.JwtUtil;
import com.xyxeshang.es.music.backend.util.ResultUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author xyx-Eshang
 */
@Aspect
@Component
public class JwtCheckAspect {
	@Resource
	HttpServletRequest request;

	public static String headerName;

	@Around("@annotation(jwtCheck)")
	public Object jwtCheckAdvice(ProceedingJoinPoint pjp, JwtCheck jwtCheck) throws Throwable {
		try {
			//获取请求头中的token
			String token = request.getHeader(headerName);
			Claims claims;
			//检验是否有效
			try {
				claims = JwtUtil.parseToken(token);
			} catch (IllegalArgumentException e) {
				//token为空
				throw new CustomException(ResultConstant.TOKEN_IS_NULL);
			} catch (SignatureException | MalformedJwtException e){
				//token是伪造的
				throw new CustomException(ResultConstant.TOKEN_IS_FAKE);
			}catch(ExpiredJwtException e){
				//token已过期
				throw new CustomException(ResultConstant.TOKEN_HAS_EXPIRED);
			}
			//没抛出异常，则说明token有效，此时将用户信息取出，放入请求的attribute中
			String userOpenId = (String) claims.get("userOpenId");

			request.setAttribute("userOpenId", userOpenId);
			//放行
			return pjp.proceed();
		} catch (Exception e) {
			return new ResultUtil<>(e);
		}
	}

	public static String getHeaderName() {
		return headerName;
	}

	@Value("${JWT_HEADER_NAME}")
	public void setHeaderName(String headerName) {
		JwtCheckAspect.headerName = headerName;
	}
}
